package com.hzz.service.user;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hzz.api.user.IUserService;
import com.hzz.dao.analysis.IAnalysisRiverSupervisorDao;
import com.hzz.dao.river.IChannelInfoDao;
import com.hzz.dao.river.IRiverInfoDao;
import com.hzz.dao.sys.ISysVariableDao;
import com.hzz.dao.user.*;
import com.hzz.dto.user.AuthRoleDto;
import com.hzz.dto.user.AuthUserVsRoleDto;
import com.hzz.dto.user.UserDto;
import com.hzz.entity.river.RiverInfo;
import com.hzz.entity.user.AuthUserVsRole;
import com.hzz.entity.user.User;
import com.hzz.framework.Response;
import com.hzz.framework.SysErrorCode;
import com.hzz.framework.annotation.ALogOperation;
import com.hzz.framework.annotation.RfUser2Bean;
import com.hzz.framework.exception.ServiceException;
import com.hzz.framework.security.MD5;
import com.hzz.framework.service.BaseService;
import com.hzz.framework.util.CommonConstant;
import com.hzz.framework.util.IdUtil;
import com.hzz.framework.util.JwtUtil;
import com.hzz.framework.util.ValidatorUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class UserService extends BaseService implements IUserService {
    @Autowired
    IUserDao userDao;
    @Autowired
    IAuthRoleDao authRoleDao;
    @Autowired
    ISysVariableDao sysVariableDao;
    @Autowired
    IOrgInfoDao orgInfoDao;
    @Autowired
    IAuthRoleVsOrgDao authRoleVsOrgDao;
    @Autowired
    IAuthUserVsOrgDao authUserVsOrgDao;
    @Autowired
    IAuthUserVsRoleDao authUserVsRoleDao;
    @Autowired
    IAnalysisRiverSupervisorDao analysisRiverSupervisorDao;
    @Autowired
    IRiverInfoDao riverInfoDao;
    @Autowired
    IChannelInfoDao channelInfoDao;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = CommonConstant.DB_DEFAULT_TIMEOUT, rollbackFor = {Exception.class, RuntimeException.class})
//    @RfUser2Bean
    @ALogOperation(type = "修改", desc = "用户管理")
    public Response saveOrUpdateData(UserDto dto) {
        Response result = new Response(0, "success");
        try {
            User entity = copyTo(dto, User.class);
            if (null == entity.getState()) {
                entity.setState(0);//在职
            }
            // 判断数据是否存在
            if (entity.getId() != null && userDao.isDataExist(entity) > 0) {
                // 数据存在
                userDao.update(entity);
            } else {
                if (!JwtUtil.isPermitted("user:add")) {
                    throw new RuntimeException("没用新增员工的权限!");
                }
                if (userDao.isAccountExist(dto.getAccount()) > 0) {
                    throw new RuntimeException("账号已存在!");
                }
                entity.setPassword(MD5.passwordMd5Hex(entity.getPassword()));
                // 新增
                entity.setId(IdUtil.nextId());
                userDao.insert(entity);
                result.data = entity.getId();
                // 根据用户类型(1,2) 分配用户角色 用户类型 -1:超级管理员,0:管理员,1:河长,2:普通人员
                if (CommonConstant.TYPES_各河长.indexOf(entity.getType()) != -1) {
                    AuthUserVsRole authUserVsRole = new AuthUserVsRole();
                    authUserVsRole.setUserId(entity.getId());
                    authUserVsRole.setRoleId(1L);
                    authUserVsRoleDao.insert(authUserVsRole);
                }
                if (CommonConstant.TYPE_普通人员 == entity.getType()) {
                    AuthUserVsRole authUserVsRole = new AuthUserVsRole();
                    authUserVsRole.setUserId(entity.getId());
                    switch (entity.getJob()) {
                        case "河长办人员": {
                            authUserVsRole.setRoleId(2L);
                            break;
                        }
                        case "巡查员": {
                            authUserVsRole.setRoleId(3L);
                            break;
                        }
                        case "监督员": {
                            authUserVsRole.setRoleId(4L);
                            break;
                        }
                    }
                    authUserVsRoleDao.insert(authUserVsRole);
                }
            }
        } catch (Exception e) {
            log.error("信息保存失败!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return result;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = CommonConstant.DB_DEFAULT_TIMEOUT, rollbackFor = {Exception.class, RuntimeException.class})
    @RfUser2Bean
    public Response insert(UserDto dto) {
        Response result = new Response(0, "success");
        try {
            User entity = copyTo(dto, User.class);
            // 判断数据是否存在
            if (userDao.isDataExist(entity) != 0) {
                // 数据存在
            } else {
                if (!JwtUtil.isPermitted("user:add")) {
                    throw new RuntimeException("没用新增员工的权限!");
                }
                if (userDao.isAccountExist(dto.getAccount()) > 0) {
                    throw new RuntimeException("账号已存在!");
                }
                entity.setPassword(MD5.passwordMd5Hex(entity.getPassword()));
                // 新增
                userDao.insert(entity);
                result.data = entity.getId();
            }
        } catch (Exception e) {
            log.error("信息保存失败!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return result;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = CommonConstant.DB_DEFAULT_TIMEOUT, rollbackFor = {Exception.class, RuntimeException.class})
    @RfUser2Bean
    public String updateData(UserDto dto) {
        String result = "success";
        try {
            User entity = copyTo(dto, User.class);
            // 判断数据是否存在
            if (userDao.isDataExist(entity) != 0) {
                // 数据存在
                userDao.update(entity);
            }
        } catch (Exception e) {
            log.error("信息更新失败!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return result;
    }

    @Override
    public String deleteData(UserDto dto) {
        String result = "success";
        try {
            userDao.deleteByPrimaryKey(copyTo(dto, User.class));
        } catch (Exception e) {
            log.error("信息删除失败!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return result;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = CommonConstant.DB_DEFAULT_TIMEOUT, rollbackFor = {Exception.class, RuntimeException.class})
    @RfUser2Bean
    @ALogOperation(type = "删除", desc = "用户管理")
    public String deleteDataById(UserDto dto) {
        String result = "success";
        try {
            userDao.deleteById(copyTo(dto, User.class));
        } catch (Exception e) {
            log.error("信息删除失败!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return result;
    }

    @Override
    public PageInfo findDataIsPage(UserDto dto) {
        PageInfo pageInfo = null;
        try {
            User entity = copyTo(dto, User.class);
            PageHelper.startPage(PN(dto.getPageNum()), PS(dto.getPageSize()));
            List list = userDao.findDataIsPage(entity);
            pageInfo = new PageInfo(list);
            pageInfo.setList(copyTo(pageInfo.getList(), UserDto.class));
        } catch (Exception e) {
            log.error("信息[分页]查询异常!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return pageInfo;
    }

    @Override
    public List<UserDto> findDataIsList(UserDto dto) {
        List<UserDto> results = null;
        try {
            results = copyTo(userDao.findDataIsList(copyTo(dto, User.class)), UserDto.class);
        } catch (Exception e) {
            log.error("信息查询失败!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return results;
    }

    @Override
    public UserDto findDataById(UserDto dto) {
        UserDto result = null;
        try {
            result = copyTo(userDao.selectByPrimaryKey(copyTo(dto, User.class)), UserDto.class);
        } catch (Exception e) {
            log.error("信息详情byid查询失败!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return result;
    }

    @Override
    public String recoveryDataById(UserDto dto) {
        String result = "success";
        try {
            userDao.recoveryDataById(copyTo(dto, User.class));
        } catch (Exception e) {
            result = "信息恢复失败!";
            log.error(result, e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return result;
    }

    @Override
    public String isAccountExist(String account) {
        String result = "success";
        try {
            if (ValidatorUtil.notEmpty(account)) {
                if (userDao.isAccountExist(account) > 0) {
                    throw new RuntimeException("账号[" + account + "]已存在!");
                }
            }
        } catch (Exception e) {
            log.error("判断员工account是否存在,数据库处理异常!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return result;
    }

    @Override
    @RfUser2Bean
    @ALogOperation(type = "修改", desc = "员工密码")
    public String updatePassword(UserDto dto) {
        String result = "success";
        try {
            if (!dto.getNewPassword().equals(dto.getConfirmPassword())) {
                throw new RuntimeException("两次密码不一致!");
            }
            UserDto userDto = copyTo(userDao.selectUserPasswordByPrimaryKey(copyTo(dto, User.class)), UserDto.class);
            if (userDto == null) {
                throw new RuntimeException("账号不存在!");
            }

            userDto.setOriginalPassword(MD5.passwordMd5Hex(dto.getOriginalPassword()));
            userDto.setConfirmPassword(MD5.passwordMd5Hex(dto.getConfirmPassword()));

            if (!userDto.getPassword().equals(userDto.getOriginalPassword())) {
                throw new RuntimeException("原密码错误!");
            }
            if (userDao.updatePassword(copyTo(userDto, User.class)) == 0) {
                throw new RuntimeException("密码修改失败,请重试!");
            }
        } catch (Exception e) {
            log.error("修改密码异常!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return result;
    }

    @Override
    @RfUser2Bean
    @ALogOperation(type = "修改", desc = "员工密码重置")
    public String resetPassword(UserDto dto) {
        try {
            String newPassword = CommonConstant.DEFAULT_RESET_PASSWORD;// IdUtil.createUUID(8);
            dto.setPassword(MD5.passwordMd5Hex(MD5.md5Hex(newPassword)));
            if (userDao.resetPassword(copyTo(dto, User.class)) == 0) {
                throw new RuntimeException("密码重置失败,请重试!");
            }
            return newPassword;
        } catch (Exception e) {
            log.error("密码重置失败!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
    }

    @Override
    @RfUser2Bean
    @ALogOperation(type = "修改", desc = "账号停用")
    public String disabled(UserDto dto) {
        String result = "success";
        try {
            if (userDao.disabled(copyTo(dto, User.class)) == 0) {
                throw new RuntimeException("操作失败,请重试!");
            }
        } catch (Exception e) {
            log.error("密码重置失败!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return result;
    }

    @Override
    public List<UserDto> findRiverStaffIsList(UserDto dto) {
        List<UserDto> results = null;
        try {
            results = copyTo(userDao.findRiverStaffIsList(copyTo(dto, User.class)), UserDto.class);
        } catch (Exception e) {
            log.error("信息查询失败!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return results;
    }

    @Override
    public List<AuthRoleDto> findUserRoleIsList(UserDto dto) {
        List<AuthRoleDto> results = null;
        try {
            AuthUserVsRole userVsRole = new AuthUserVsRole();
            userVsRole.setUserId(dto.getId());
            results = copyTo(authUserVsRoleDao.findUserRoleIsList(userVsRole), AuthRoleDto.class);

        } catch (Exception e) {
            log.error("获取员工->个人角色。异常!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return results;
    }

    @Override
    public List<AuthRoleDto> findOrgRoleIsList(UserDto dto) {
        List<AuthRoleDto> results = null;
        try {
            AuthUserVsRole userVsRole = new AuthUserVsRole();
            userVsRole.setUserId(dto.getId());
            results = copyTo(authUserVsRoleDao.findOrgRoleIsList(userVsRole), AuthRoleDto.class);

        } catch (Exception e) {
            log.error("获取员工->组织角色。异常!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return results;
    }

    @Override
    @RfUser2Bean
    //@RequiresPermissions("user:edit:role")
    public Response addRole(AuthUserVsRoleDto dto) {
        Response result = new Response(0, "success");
        try {
            authUserVsRoleDao.insert(copyTo(dto, AuthUserVsRole.class));
        } catch (Exception e) {
            log.error("信息保存失败!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return result;
    }

    //@RequiresPermissions("user:edit:role")
    @Override
    public Response delRole(AuthUserVsRoleDto dto) {
        Response result = new Response(0, "success");
        try {
            authUserVsRoleDao.deleteByPrimaryKey(copyTo(dto, AuthUserVsRole.class));
        } catch (Exception e) {
            log.error("信息保存失败!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return result;
    }

    @Override
    public List<UserDto> findUserByRoleIsList(AuthUserVsRoleDto dto) {
        List<UserDto> results = null;
        try {
            AuthUserVsRole userVsRole = new AuthUserVsRole();
            userVsRole.setRoleId(dto.getRoleId());
            results = copyTo(authUserVsRoleDao.findUserByRoleIsList(userVsRole), UserDto.class);
        } catch (Exception e) {
            log.error("根据角色id->获取用户列表。异常!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return results;
    }

    @Override
    public PageInfo findUserByRoleIsPage(AuthUserVsRoleDto dto) {
        PageInfo pageInfo = null;
        try {
            AuthUserVsRole entity = copyTo(dto, AuthUserVsRole.class);
            PageHelper.startPage(PN(dto.getPageNum()), PS(dto.getPageSize()));
            List list = authUserVsRoleDao.findUserByRoleIsList(entity);
            pageInfo = new PageInfo(list);
            pageInfo.setList(copyTo(pageInfo.getList(), UserDto.class));
        } catch (Exception e) {
            log.error("根据角色id->获取用户列表。异常!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return pageInfo;
    }

    @Override
    public Map findRiverDataByUserId(UserDto staffDto) throws Exception {
        Map result = new HashMap();
        try {
            User entity = new User();
            entity.setId(staffDto.getId());
            entity.setStaffId(staffDto.getId());
            entity.setType(staffDto.getType());
            // 水域类型(1河流,2水库,3渠道)
            // 1河流
            List<RiverInfo> typeRivierList = new ArrayList<>();
            // 2水库
            List<RiverInfo> typeReservoirList = new ArrayList<>();
            // 3渠道
            List<RiverInfo> channelInfoList = new ArrayList<>();
            List<RiverInfo> riverInfoList = riverInfoDao.findDataListByUserId(entity);
            if (riverInfoList != null) {
                for (RiverInfo riverInfo : riverInfoList) {
                    if (1 == riverInfo.getType()) {
                        typeRivierList.add(riverInfo);
                    } else if (2 == riverInfo.getType()) {
                        typeReservoirList.add(riverInfo);
                    } else if (3 == riverInfo.getType()) {
                        channelInfoList.add(riverInfo);
                    }
                    riverInfo.setType(null);
                }
            }
            result.put("river", typeRivierList);
            result.put("reservoir", typeReservoirList);
            result.put("channel", channelInfoList);
        } catch (Exception e) {
            log.error("根据用户查找河道-水库-渠道。异常!", e);
            throw new ServiceException(SysErrorCode.defaultError, e);
        }
        return result;
    }
}
